#include "mergewidget.h"
#include "ui_widget.h"

#include <QFileDialog>
#include <QMessageBox>
#include <QProcess>

#include "widget.h"

MergeWidget::MergeWidget(QWidget *parent, Ui::Widget *ui) : QWidget(parent), ui(ui)
{
}

MergeWidget::~MergeWidget()
{
    // 不需要删除ui,因为它是从外部传入的
}


void MergeWidget::onAddFile(Widget* widget)
{
    QStringList files = QFileDialog::getOpenFileNames(
        widget,
        tr("选择要合并的文件"),
        QString(),
        tr("媒体文件 (*.mp4 *.avi *.mkv *.mov *.ts *.mp3 *.wav);;所有文件 (*.*)")
    );

    for(const QString& file : files) {
        widget->findChild<QListWidget*>("fileListWidget")->addItem(file);
    }
}

void MergeWidget::onRemoveFile(Widget* widget)
{
    delete widget->findChild<QListWidget*>("fileListWidget")->currentItem();
}

void MergeWidget::onMoveUp(Widget* widget)
{
    int currentRow = widget->findChild<QListWidget*>("fileListWidget")->currentRow();
    if(currentRow > 0) {
        QListWidgetItem *item = widget->findChild<QListWidget*>("fileListWidget")->takeItem(currentRow);
        widget->findChild<QListWidget*>("fileListWidget")->insertItem(currentRow - 1, item);
        widget->findChild<QListWidget*>("fileListWidget")->setCurrentItem(item);
    }
}

void MergeWidget::onMoveDown(Widget* widget)
{
    int currentRow = widget->findChild<QListWidget*>("fileListWidget")->currentRow();
    if(currentRow < widget->findChild<QListWidget*>("fileListWidget")->count() - 1) {
        QListWidgetItem *item = widget->findChild<QListWidget*>("fileListWidget")->takeItem(currentRow);
        widget->findChild<QListWidget*>("fileListWidget")->insertItem(currentRow + 1, item);
        widget->findChild<QListWidget*>("fileListWidget")->setCurrentItem(item);
    }
}

void MergeWidget::onOutputPathSelect(Widget* widget)
{
    QString dir = QFileDialog::getExistingDirectory(
        widget,
        tr("选择输出目录"),
        QString(),
        QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks
    );

    if(!dir.isEmpty()) {
        widget->findChild<QLineEdit*>("outputPathEdit")->setText(dir);

        // 创建fileList.txt
        QFile file("fileList.txt");
        if(file.open(QIODevice::WriteOnly | QIODevice::Text)) {
            QTextStream stream(&file);
            QListWidget* fileList = widget->findChild<QListWidget*>("fileListWidget");
            for(int i = 0; i < fileList->count(); i++) {
                stream << "file '" << fileList->item(i)->text() << "'\n";
            }
            file.close();
        }
    }
}

void MergeWidget::onRunMerge(Widget* widget)
{
    // 检查文件列表和输出路径
    if (widget->findChild<QListWidget*>("fileListWidget")->count() == 0) {
        QMessageBox::warning(widget, "错误", "请添加需要合并的文件");
        return;
    }
    if (widget->findChild<QLineEdit*>("outputPathEdit")->text().isEmpty()) {
        QMessageBox::warning(widget, "错误", "请设置输出目录");
        return;
    }

    QString cmd = QString("\"%1\" ").arg(Widget::getFFmpegPath());
    QString outputPath = widget->findChild<QLineEdit*>("outputPathEdit")->text();
    QString fullOutputPath = outputPath + "/output.mp4";

    // 根据不同的合并选项构建命令
    if (widget->findChild<QRadioButton*>("noCopyRadio")->isChecked()) {
        // 不编解码合并
        // 使用concat demuxer方式合并
        cmd += QString(" -y -hide_banner -vsync 0 -safe 0 -f concat -i \"fileList.txt\" -c copy \"%1\"").arg(fullOutputPath);
    }
    else if (widget->findChild<QRadioButton*>("tsRadio")->isChecked()) {
        // 转ts再合并
        QString tempDir = QDir::tempPath() + "/ffmpeg_merge/";
        QDir().mkpath(tempDir);

        // 先转成ts
        QStringList tsFiles;
        for (int i = 0; i < widget->findChild<QListWidget*>("mergeFileList")->count(); i++) {
            QString inputFile = widget->findChild<QListWidget*>("mergeFileList")->item(i)->text();
            QString tsFile = tempDir + QString::number(i) + ".ts";
            tsFiles << tsFile;

            QString convertCmd = QString("\"%1\" -i \"%2\" -c copy -bsf:v h264_mp4toannexb -f mpegts \"%3\"")
                               .arg(Widget::getFFmpegPath(), inputFile, tsFile);
            QProcess::execute(convertCmd);
        }

        // 合并ts
        QString concat = "concat:";
        for (int i = 0; i < tsFiles.size(); i++) {
            if (i > 0) concat += "|";
            concat += tsFiles[i];
        }
        cmd += QString("-i \"%1\" -c copy -bsf:a aac_adtstoasc \"%2\"").arg(concat, fullOutputPath);
    }
    else if (widget->findChild<QRadioButton*>("videoFilterRadio")->isChecked()) {
        // 视频滤镜合并
        QString filter = "concat=n=" + QString::number(widget->findChild<QListWidget*>("mergeFileList")->count()) + ":v=1:a=0";
        for (int i = 0; i < widget->findChild<QListWidget*>("mergeFileList")->count(); i++) {
            cmd += QString("-i \"%1\" ").arg(widget->findChild<QListWidget*>("mergeFileList")->item(i)->text());
        }
        cmd += QString("-filter_complex \"%1\" \"%2\"").arg(filter, fullOutputPath);
    }
    else if (widget->findChild<QRadioButton*>("audioFilterRadio")->isChecked()) {
        // 音频滤镜合并
        QString filter = "concat=n=" + QString::number(widget->findChild<QListWidget*>("mergeFileList")->count()) + ":v=0:a=1";
        for (int i = 0; i < widget->findChild<QListWidget*>("mergeFileList")->count(); i++) {
            cmd += QString("-i \"%1\" ").arg(widget->findChild<QListWidget*>("mergeFileList")->item(i)->text());
        }
        cmd += QString("-filter_complex \"%1\" \"%2\"").arg(filter, fullOutputPath);
    }

    // 显示命令并执行
    widget->findChild<QTextEdit*>("mergeLogEdit")->setText("<font color='blue'>转换命令：</font>");
    widget->findChild<QTextEdit*>("mergeLogEdit")->setText("<font color='blue'>" + cmd + "</font>");

    QProcess process;
    process.setProcessChannelMode(QProcess::MergedChannels);
    process.start(cmd);

    while (process.state() != QProcess::NotRunning) {
        process.waitForReadyRead();
        QByteArray output = process.readAll();
        if (!output.isEmpty()) {
            widget->findChild<QTextEdit*>("mergeLogEdit")->append(QString::fromUtf8(output));
        }
    }

    widget->findChild<QTextEdit*>("mergeLogEdit")->append("<font color='green'>合并完成！</font>");
}